﻿using JetBrains.Annotations;
using Volo.Abp;

namespace System.ComponentModel.DataAnnotations;

/// <summary>
/// Maps a static CLR method to a database function so that the CLR method may be used in LINQ queries. By convention uses the .NET method name as name of the database function and the default schema.
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public class DbFunctionAttribute : Attribute
{
    private string _name;

    private string _schema;

    private bool _builtIn;

    private bool? _nullable;

    /// <summary>
    /// The name of the function in the database.
    /// </summary>
    public virtual string Name
    {
        get
        {
            return _name;
        }
        [param: NotNull]
        set
        {
            Check.NotNullOrEmpty(value, "value");
            _name = value;
        }
    }

    /// <summary>
    /// The schema of the function in the database.
    /// </summary>
    public virtual string Schema
    {
        get
        {
            return _schema;
        }
        [param: CanBeNull]
        set
        {
            _schema = value;
        }
    }

    /// <summary>
    /// The value indicating whether the database function is built-in or not.
    /// </summary>
    public virtual bool IsBuiltIn
    {
        get
        {
            return _builtIn;
        }
        set
        {
            _builtIn = value;
        }
    }

    /// <summary>
    /// The value indicating whether the database function can return null result or not.
    /// </summary>
    public virtual bool IsNullable
    {
        get
        {
            return _nullable ?? true;
        }
        set
        {
            _nullable = value;
        }
    }

    /// <summary>
    /// Checks whether Microsoft.EntityFrameworkCore.DbFunctionAttribute.IsNullable has been explicitly set to a value.
    /// </summary>
    public bool IsNullableHasValue => _nullable.HasValue;

    /// <summary>
    /// Initializes a new instance of the Microsoft.EntityFrameworkCore.DbFunctionAttribute class.
    /// </summary>
    public DbFunctionAttribute()
    {
    }

    /// <summary>
    /// Initializes a new instance of the Microsoft.EntityFrameworkCore.DbFunctionAttribute class.
    /// </summary>
    /// <param name="name">The name of the function in the database.</param>
    /// <param name="schema">The schema of the function in the database.</param>
    public DbFunctionAttribute([NotNull] string name, [CanBeNull] string schema = null)
    {
        Check.NotNullOrEmpty(name, nameof(name));
        _name = name;
        _schema = schema;
    }
}

